#include "mainframe.h"
#include "ui_mainframe.h"

#include "updater.h"
#include "server.h"

MainFrame::MainFrame(QWidget *parent)
    : QWidget(parent), ui(new Ui::MainFrame)
{
    ui->setupUi(this);

    up = new Updater(this);
    connect(up, SIGNAL(stateChanged(int)), this, SLOT(stateChanged(int)));

    connect(ui->pbConnect, SIGNAL(clicked()), this, SLOT(doUpdate()));

    ui->progressBar->setValue(0);
    ui->stack->setCurrentIndex(0);

    ui->packs->header()->setResizeMode(QHeaderView::ResizeToContents);

    // actions
    actionMenu = new QMenu(this);
    actionMenu->addAction("Skip", this, SLOT(skipItems()));
    actionMenu->addAction("Install/Update", this, SLOT(installItems()));
    actionMenu->addAction("Reload/Reinstall", this, SLOT(reloadItems()));
}

MainFrame::~MainFrame()
{
    delete ui;
}

void MainFrame::doUpdate()
{
  int res;

  up->setDownloadPath(QDir::tempPath() + "/xlabsoft/jag");
  up->setRootPath("jag"); // path on server

  res = up->loadInstalledInfo("version");
  if (res <= 0)
  {
    ui->log->append("Cannot retrieve installation info.");
  }

  ServerInfo info;
  info.host = "jag.xlabsoft.com";
  info.port = 80;
  //info.host = "ftp.xlabsoft.com";
  info.dir = "files";
  //info.port = 21;
  info.user = "anonimous";

  up->setServerInfo(info);
  res = up->connectServer();
  if (res <= 0)
  {
    ui->log->append("Cannot login to the server.");
    return;
  }

  ui->log->append("Login successful. Retrieving package list...");
  ui->lFile->setText("version");

  //res = up->downloadVersion("files", "version");
  res = up->downloadVersion("/files/version", "version");

  if (res <= 0)
  {
    ui->log->append("Cannot retrieve packet information.");
    return;
  }

  ui->log->append("Package list retrieved.");

  doUpdatePackageList();
}

void MainFrame::stateChanged(int state)
{
    switch (state)
    {
        case QFtp::Unconnected:
            ui->lState->setText( "Not connected" );
            return;

        case QFtp::HostLookup:
            ui->lState->setText( "Looking for a host..." );
            return;

        case QFtp::Connecting:
            ui->lState->setText( "Connecting..." );
            return;

        case QFtp::Connected:
            ui->lState->setText( "Connected to host." );
            return;

        case QFtp::LoggedIn:
            ui->lState->setText( "Connected and logged." );
            return;

        case QFtp::Closing:
            ui->lState->setText( "Disconnecting..." );
            return;
    }
}

void MainFrame::doUpdatePackageList()
{
  ui->stack->setCurrentIndex(1);
  ui->packs->setUpdatesEnabled(false);
  ui->packs->clear();

  QMap<QString, PackageInfo>::iterator it, it_end = up->data().packs().end();
  for (it = up->data().packs().begin(); it != it_end; it++)
  {
    PackageInfo &pack = *it;
    QTreeWidgetItem *item = new QTreeWidgetItem(ui->packs);
    item->setData(0,1000, pack.name);
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);

    item->setText(0, pack.name);

    if (pack.versionInstalled)
    {
      item->setText(1, pack.versionInstalledText);
      item->setCheckState(0, Qt::Checked);
    }
    else
    {
      item->setText(1, "not installed");
      item->setCheckState(0, Qt::Unchecked);
    }

    if (pack.versionServer)
    {
      item->setText(2, pack.versionServerText);
      if (pack.versionServer > pack.versionInstalled)
      {
        item->setForeground(0, Qt::darkGreen);
        item->setForeground(2, Qt::darkGreen);
        item->setForeground(4, Qt::darkGreen);
      }
    }
    else
      item->setText(2, "not found");

    QString txt;
    switch (pack.state)
    {
      case None:
        txt = "";
        item->setDisabled(true);
        break;
      case Installed: txt = "installed";    break;
      case NotLoaded: txt = "not loaded";   break;
      case Broken:    txt = "broken";       break;
      case Partial:   txt = "half loaded";  break;
      case Loaded:    txt = "loaded";       break;
    }
    item->setText(3, txt);

    switch (pack.action)
    {
      case Skip:          txt = "skip";             break;
      case Install:       txt = "install";          break;
      case ReloadInstall: txt = "reload & install"; break;
      case LoadInstall:   txt = "load & install";   break;
    }
    item->setText(4, txt);
  }

  ui->packs->setUpdatesEnabled(true);
}


void MainFrame::on_packs_itemPressed ( QTreeWidgetItem * item, int column )
{
  if (!item)
    return;

  if (QApplication::mouseButtons() & Qt::RightButton)
    actionMenu->popup(QCursor::pos());
}

QList<PackageInfo*> MainFrame::getSelectedPackages()
{
  QList<PackageInfo*> packages;
  QMap<QString, PackageInfo>& packs = up->data().packs();

  QList<QTreeWidgetItem *> items = ui->packs->selectedItems();
  for (int i = 0; i < items.count(); i++)
  {
    QTreeWidgetItem *item = items.at(i);
    if (item->isDisabled())
      continue;

    packages.append(&packs[item->data(0,1000).toString()]);
  }

  return packages;
}

void MainFrame::skipItems()
{
  QList<PackageInfo*> packages = getSelectedPackages();
  for (int i = 0; i < packages.count(); i++)
  {
    PackageInfo *pinfo = packages.at(i);
    pinfo->action = Skip;
  }

  doUpdatePackageList();
}

void MainFrame::installItems()
{
  QList<PackageInfo*> packages = getSelectedPackages();
  for (int i = 0; i < packages.count(); i++)
  {
    PackageInfo *pinfo = packages.at(i);
    switch (pinfo->state)
    {
      case NotLoaded:
      case Partial:
        pinfo->action = LoadInstall;
        break;
      case Broken:
        pinfo->action = ReloadInstall;
        break;
      case Loaded:
        pinfo->action = Install;
        break;
    }
  }

  doUpdatePackageList();
}
